<?php
App::uses('AppController', 'Controller');
App::uses('BipartiteGraphException', 'Vendor/DPD');
App::uses('BipartiteGraph', 'Vendor/DPD');
App::uses('TeacherDAO', 'Vendor/DPD');
App::uses('DisciplineDAO', 'Vendor/DPD');
App::uses('Process', 'Vendor/DPD');

class DistributionsController extends AppController
{
	var $components = array('RequestHandler', 'AjaxMultiUpload.Upload');
	public function index(){
		$this->set('distributions', $this->paginate('Distribution'));
	}

	public function delete($id = null) {
		if (!$this->request->is('post')) {
			throw new MethodNotAllowedException();
		}
		$this->Distribution->id = $id;
		if (!$this->Distribution->exists()) {
			throw new NotFoundException(__('Invalid distribution'));
		}
		unlink('xmls/'.$this->Distribution->field('salt').'.xml');
		if ($this->Distribution->delete()) {
			$this->Session->setFlash(__('Distribution deleted'));
			$this->redirect(array('action' => 'index'));
		}
		$this->Session->setFlash(__('Distribution was not deleted'));
		$this->redirect(array('action' => 'index'));
	}


	public function makeCopy($id){
		$this->Distribution->read(null, $id);

		
		$data = array("Distribution"=> array(
					'year' => $this->Distribution->field('year'),
					'name' =>$this->Distribution->field('name'),
					'user' => AuthComponent::user('id')
				));
		$name = $this->Distribution->field('salt');
		$this->Distribution->create();

		$this->Distribution->save($data);

		$salt = sha1($this->Distribution->id.time());

		copy("xmls/".$name.".xml", "xmls/".$salt.".xml");

		$this->Distribution->save(array("Distribution" => array("salt" => $salt)));

		$this->Session->setFlash(__("Distribution copied!"));

		$this->redirect(array('action' => 'edit', $this->Distribution->id));
	}

	public function edit($id){

		$this->loadModel('Teacher');
		$this->loadModel('Discipline');
		$this->loadModel('DisciplinesTeacher');
		//$this->Distribution->read(null, $id);
		$teachers = $this->Teacher->find('all', array('order' => array('Teacher.name' => 'ASC')));
		if($this->request->is('post') ||$this->request->is('put'))
		{
			
			$distribution = new SimpleXMLElement('<distribution name="'.$this->request->data['Distribution']['name'].'" year="'.$this->request->data['Distribution']['year'].'" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="distribution.xsd" ></distribution>');

			$teachersNode = $distribution->addChild('teachers');
			foreach ($teachers as $professor) {
				$teacherNode = $teachersNode->addChild('teacher');
				$teacherNode->addChild('id', $professor['Teacher']['id']);
				$semester = $teacherNode->addChild('semester');
				$semester->addAttribute('num', '1');
				if(isset($this->request->data[$professor['Teacher']['id']][0]))
					$semester->addAttribute('available', 1);
				else
					$semester->addAttribute('available', 0);
				$semester = $teacherNode->addChild('semester');
				$semester->addAttribute('num', '2');
				if(isset($this->request->data[$professor['Teacher']['id']][1]))
					$semester->addAttribute('available', 1);
				else
					$semester->addAttribute('available', 0);
				$teacherNode->addChild('workload', $professor['Teacher']['workload']);
				$teacherNode->addChild('Aworkload', $professor['Teacher']['additional_workload']);
			}

			$relations = $distribution->addChild('relations');

			if(isset($this->request->data['Assignment']))
			{
				foreach ($this->request->data['Assignment'] as $key => $value) {
					foreach ($value as $discipline) {
						$assignment = $relations->addChild('assignment');
						$assignment->addChild('teacher', $key);
						$assignment->addChild('discipline', $discipline);
						if(isset($this->request->data['Fixed'][$key][$discipline]))
							$assignment->addChild('fixed', 1);
						else
							$assignment->addChild('fixed', 0);
					}
				}

			}

			$this->Distribution->read(null, $this->request->data['isUpdate']);

			$this->set('id', $this->Distribution->id);

			$data = array("Distribution"=> array(
					'name' => $this->request->data['Distribution']['name'],
					'year' => $this->request->data['Distribution']['year'],
					'user' => AuthComponent::user('id')
				));
			$this->Distribution->save($data);

			$distribution->asXML("xmls/".$this->Distribution->field('salt').".xml");

			$this->Session->setFlash(__('The distribution has been saved'));

			$this->redirect(array('action' => 'index', 'controller' => 'Distributions'));
		}else{
			$this->request->data = $this->Distribution->read(null, $id);
		}
		$t = array();
		foreach ($teachers as $key => $value) {
			$t[$value['Teacher']['id']] = $value;
		}
		$this->set('teachers',$t);

		$this->set('list', $this->Teacher->find('list'));

		$this->set('id', $id);

		$disciplines = $this->Discipline->find('all');
		$t = array();
		foreach ($disciplines as $key => $value) {
			$t[$value['Discipline']['id']] = $value;
		}
		$this->set('disciplines', $t);
		$name = $this->Distribution->field('salt');
		$p = new Process(array(
			'countDiscipline' => $this->DisciplinesTeacher->countWeights(),
			'weights' => $this->DisciplinesTeacher->find('all', array('order' => array('DisciplinesTeacher.id' => 'ASC'))), 'discipline' => $this->Discipline->find('all', array('order' => array('Discipline.id' => 'ASC')))), 'xmls/'.$name.'.xml', 4);
		$results = $p->getData();
		$load = $this->loadView('xmls/'.$name.'.xml', $results[2], $results[1], $results[0]);
		$p->initStatisticsAfter();
		$this->set('weightsBefore', $p->statistics['before']);
		$this->set('weightsAfter', $p->statistics['after']);
		$this->set('results', $results[0]);
		$this->set('rest1', $load['drgt']);
		$this->set('rest2', $load['dlft']);

		/* Seto a lista de professores para os Selects */

		$list1 = $this->Teacher->find('list', array('order' => array('Teacher.name' => 'ASC')));
		foreach ($list1 as $key => $value)
			if(isset($results[0][$key]) && !$results[0][$key]->getSituation(1))
				unset($list1[$key]);
			elseif(!isset($results[0][$key]))
				unset($list1[$key]);

		$this->set('list1', $list1);
		
		$list2 = $this->Teacher->find('list', array('order' => array('Teacher.name' => 'ASC')));
		foreach ($list2 as $key => $value)
			if(isset($results[0][$key]) && !$results[0][$key]->getSituation(2))
				unset($list2[$key]);
			elseif(!isset($results[0][$key]))
				unset($list2[$key]);

		$this->set('list2', $list2);
		
		$this->set('fixed', $this->getFixed("xmls/".$this->Distribution->field('salt').".xml"));

	}

	private function getFixed($name){
		$file = simplexml_load_file($name);
		 $distributions = array();

        foreach ($file->relations->assignment as $assignment) {
            if($assignment->fixed == '1')
                $distributions[(int)$assignment->teacher][(int)$assignment->discipline] = 1;
        }
        return $distributions;
	}

	public function add(){
		$this->loadModel('Teacher');
		$this->loadModel('Discipline');
		$this->loadModel('DisciplinesTeacher');
		$teachers = $this->Teacher->find('all', array('order' => array('Teacher.name' => 'ASC')));
		$this->set('teachers', $teachers);
		if($this->request->is('post'))
		{
			$distribution = new SimpleXMLElement('<distribution name="" year="'.$this->request->data['Distribution']['year'].'" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="distribution.xsd" ></distribution>');

			$teachersNode = $distribution->addChild('teachers');
			foreach ($teachers as $professor) {
				$teacherNode = $teachersNode->addChild('teacher');
				$teacherNode->addChild('id', $professor['Teacher']['id']);
				$semester = $teacherNode->addChild('semester');
				$semester->addAttribute('num', '1');
				if(isset($this->request->data[$professor['Teacher']['id']][0]))
					$semester->addAttribute('available', 1);
				else
					$semester->addAttribute('available', 0);
				$semester = $teacherNode->addChild('semester');
				$semester->addAttribute('num', '2');
				if(isset($this->request->data[$professor['Teacher']['id']][1]))
					$semester->addAttribute('available', 1);
				else
					$semester->addAttribute('available', 0);
				$teacherNode->addChild('workload', $professor['Teacher']['workload']);
				$teacherNode->addChild('Aworkload', $professor['Teacher']['additional_workload']);
			}

			$relations = $distribution->addChild('relations');

			if(isset($this->request->data['Assignment']))
			{
				foreach ($this->request->data['Assignment'] as $key => $value) {
					foreach ($value as $discipline) {
						$assignment = $relations->addChild('assignment');
						$assignment->addChild('teacher', $key);
						$assignment->addChild('discipline', $discipline);
						if(isset($this->request->data['Fixed'][$key][$discipline]))
							$assignment->addChild('fixed', 1);
						else
							$assignment->addChild('fixed', 0);
					}
				}

			}

			$this->Distribution->read(null, $this->request->data['isUpdate']);

			$this->set('id', $this->Distribution->id);

			$data = array("Distribution"=> array(
					'name' => $this->request->data['Distribution']['name'],
					'year' => $this->request->data['Distribution']['year'],
					'user' => AuthComponent::user('id')
				));
			$this->Distribution->save($data);

			$distribution->asXML("xmls/".$this->Distribution->field('salt').".xml");

			$this->Session->setFlash(__('The distribution has been saved'));

			$this->redirect(array('action' => 'index', 'controller' => 'Distributions'));
		}
	}

	private function loadView($name, $dlft, $drgt, $teacher){
		$file = simplexml_load_file($name);
		 $distributions = array();

        foreach ($file->relations->assignment as $assignment) {
            if($assignment->fixed == '0')
                $distributions[] = array('discipline' => (int)$assignment->discipline, 'teacher' => (int)$assignment->teacher);
        }



        foreach ($distributions as $distribution):
            if (isset($dlft[$distribution['discipline']])) {
                if ($teacher[$distribution['teacher']]->addDiscipline($dlft[$distribution['discipline']]))
                    unset($dlft[$distribution['discipline']]);
            }elseif (isset($drgt[$distribution['discipline']])) {
                if ($teacher[$distribution['teacher']]->addDiscipline($drgt[$distribution['discipline']]))
                    unset($drgt[$distribution['discipline']]);
            }
        endforeach;
        unset($fixeds);
        return compact("dlft", "drgt");

	}

	public function setNow($id){
		$last = $this->Distribution->find('first', array('conditions' => array('Distribution.now' => 1)));
		
		if(count($last) && $last['Distribution']['id'] != $id)
		{
			$this->Session->setFlash(__('A distribuition already set to actually'));
            $this->redirect(array('action' => 'index'));
		}

		$this->Distribution->read(null, $id);

		if($this->Distribution->field('now'))
			$data = array('Distribution' => array('now' => 0));
		else
			$data = array('Distribution' => array('now' => 1));
		if ($this->Distribution->save($data)) {
                $this->Session->setFlash(__('Distribuition actually has been set'));
                $this->redirect(array('action' => 'index'));
        } else {
            $this->Session->setFlash(__('Please, try again'));
        }
	}

	public function view($id){
		$this->loadModel('Teacher');
		$this->loadModel('Discipline');
		$this->loadModel('DisciplinesTeacher');
		$this->Distribution->read(null, $id);

		$teachers = $this->Teacher->find('all', array('order' => array('Teacher.name' => 'ASC')));
		$this->loadModel('Teacher');
		$this->loadModel('Discipline');
		$this->loadModel('DisciplinesTeacher');
		$teachers = $this->Teacher->find('all', array('order' => array('Teacher.name' => 'ASC')));

		$teachers = $this->Teacher->find('all');
		$t = array();
		foreach ($teachers as $key => $value) {
			$t[$value['Teacher']['id']] = $value;
		}
		$this->set('teachers',$t);

		$this->set('list', $this->Teacher->find('list'));

		$this->set('id', $id);

		$disciplines = $this->Discipline->find('all');
		$t = array();
		foreach ($disciplines as $key => $value) {
			$t[$value['Discipline']['id']] = $value;
		}
		$this->set('disciplines', $t);
		$name = $this->Distribution->field('salt');
		$p = new Process(array(
			'countDiscipline' => $this->DisciplinesTeacher->countWeights(),
			'weights' => $this->DisciplinesTeacher->find('all', array('order' => array('DisciplinesTeacher.id' => 'ASC'))), 'discipline' => $this->Discipline->find('all', array('order' => array('Discipline.id' => 'ASC')))), 'xmls/'.$name.'.xml', 4);
		$results = $p->getData();
		
		$load = $this->loadView('xmls/'.$name.'.xml', $results[2], $results[1], $results[0]);
		$p->initStatisticsAfter();
		$this->set('weightsBefore', $p->statistics['before']);
		$this->set('weightsAfter', $p->statistics['after']);
		$this->set('results', $results[0]);
		$this->set('rest1', $load['drgt']);
		$this->set('rest2', $load['dlft']);
		$this->set('ranking', $p->ranking);
		
		
		
		$this->set('sum', $this->setStatistics($p->statistics['after'], $p->statistics['before']));

		//if($this->request->is('requested'))
			//return $this->render();	
		
	}

	private function setStatistics($after , $before){
		$return['after'] = round(array_sum($after)/count($after),2);
		$return['before'] = round(array_sum($before)/count($before), 2);

		return $return;
	}

	public function viewNow(){


		$this->loadModel('Teacher');
		$this->loadModel('Discipline');
		$this->loadModel('DisciplinesTeacher');

		$dist = $this->Distribution->find('first', array('conditions' => array('Distribution.now' => 1)));
		if(count($dist))
		{
			$this->Distribution->read(null, $dist['Distribution']['id']);
			$teachers = $this->Teacher->find('all', array('order' => array('Teacher.name' => 'ASC')));
			$this->loadModel('Teacher');
			$this->loadModel('Discipline');
			$this->loadModel('DisciplinesTeacher');
			$teachers = $this->Teacher->find('all', array('order' => array('Teacher.name' => 'ASC')));

			$teachers = $this->Teacher->find('all');
			$t = array();
			foreach ($teachers as $key => $value) {
				$t[$value['Teacher']['id']] = $value;
			}
			$this->set('teachers',$t);

			$this->set('list', $this->Teacher->find('list'));

			$disciplines = $this->Discipline->find('all');
			$t = array();
			foreach ($disciplines as $key => $value) {
				$t[$value['Discipline']['id']] = $value;
			}
			$this->set('disciplines', $t);
			$name = $this->Distribution->field('salt');
			$p = new Process(array(
				'countDiscipline' => $this->DisciplinesTeacher->countWeights(),
				'weights' => $this->DisciplinesTeacher->find('all', array('order' => array('DisciplinesTeacher.id' => 'ASC'))), 'discipline' => $this->Discipline->find('all', array('order' => array('Discipline.id' => 'ASC')))), 'xmls/'.$name.'.xml', 4);
			$results = $p->getData();
			$load = $this->loadView('xmls/'.$name.'.xml', $results[2], $results[1], $results[0]);
			$p->initStatisticsAfter();
			$this->set('weightsBefore', $p->statistics['before']);
			$this->set('weightsAfter', $p->statistics['after']);
			$this->set('results', $results[0]);
			$this->set('rest1', $load['drgt']);
			$this->set('rest2', $load['dlft']);
			$this->set('ranking', $p->ranking);
			$sum = 0;
			
			foreach ($results[0] as $teacher) 
			{

				foreach ($teacher->getDisciplines() as $key => $value) {
					$sum += $teacher->getWeight($value->getId());
				}
			}
			$this->set('sum', $this->setStatistics($p->statistics['after'], $p->statistics['before']));
		}else{
			$this->autoRender = false;
		}
		

	}

	public function runGraph(){

		$this->loadModel('Teacher');
		$this->loadModel('Discipline');
		$this->loadModel('DisciplinesTeacher');

		$disSemester = $this->Discipline->find('list', array('fields' => array('Discipline.id', 'Discipline.semester')));
		if($this->RequestHandler->isAjax())
		{
			$teachers = $this->Teacher->find('all', array('order' => array('Teacher.name' => 'ASC')));
			/* Crio o XML */
			$distribution = new SimpleXMLElement('<distribution name="" year="'.$this->request->data['Distribution']['year'].'" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="distribution.xsd" ></distribution>');
			$teachersNode = $distribution->addChild('teachers');
			foreach ($teachers as $professor) {
				$teacherNode = $teachersNode->addChild('teacher');
				$teacherNode->addChild('id', $professor['Teacher']['id']);
				$semester = $teacherNode->addChild('semester');
				$semester->addAttribute('num', '1');
				if(isset($this->request->data[$professor['Teacher']['id']][0]))
					$semester->addAttribute('available', 1);
				else
					$semester->addAttribute('available', 0);
				$semester = $teacherNode->addChild('semester');
				$semester->addAttribute('num', '2');
				if(isset($this->request->data[$professor['Teacher']['id']][1]))
					$semester->addAttribute('available', 1);
				else
					$semester->addAttribute('available', 0);
				$teacherNode->addChild('workload', $professor['Teacher']['workload']);
				$teacherNode->addChild('Aworkload', $professor['Teacher']['additional_workload']);
			}

			$relations = $distribution->addChild('relations');
			
			/* Vejo se devo ou não atualizar a dist no banco */
			if(!isset($this->request->data['isUpdate']))
			{
				$data = array("Distribution"=> array(
						'name' => $this->request->data['Distribution']['name'],
						'year' => $this->request->data['Distribution']['year'],
						'user' => AuthComponent::user('id')
					));

				if(!$this->Distribution->save($data))
				{
					$this->Session->setFlash(__("Distribution already exists"));
					$this->redirect(array('action' => 'add', 'controller' => 'Distributions'));
				}
				$this->Distribution->read();
				$this->set('id', $this->Distribution->id);
				$name = sha1($this->Distribution->id.time());
				$distribution->asXML("xmls/".$name.".xml");
				$this->Distribution->save(array("Distribution" => array("salt" => $name)));
			}
			else
			{
				/* Vejo se já foi rodado pelo menos uma vez o algoritmo */
				if(isset($this->request->data['Assignment']))
				{
					foreach ($this->request->data['Assignment'] as $key => $value) {
						foreach ($value as $discipline) {
							if($disSemester[$discipline] == 1)
							{
								if(isset($this->request->data['Fixed'][$key][$discipline]) && isset($this->request->data[$key][0]))
								{
									$assignment = $relations->addChild('assignment');
									$assignment->addChild('teacher', $key);
									$assignment->addChild('discipline', $discipline);
									$assignment->addChild('fixed', 1);
								}
							}else{
								if(isset($this->request->data['Fixed'][$key][$discipline]) && isset($this->request->data[$key][1]))
								{
									$assignment = $relations->addChild('assignment');
									$assignment->addChild('teacher', $key);
									$assignment->addChild('discipline', $discipline);
									$assignment->addChild('fixed', 1);
								}
							}
							

						}
					}
				}
				if(isset($this->request->data['Fixed']))
					$this->set('fixed', $this->request->data['Fixed']);
				
				$this->Distribution->read(null, $this->request->data['isUpdate']);

				$this->set('id', $this->Distribution->id);

				$data = array("Distribution"=> array(
						'name' => $this->request->data['Distribution']['name'],
						'year' => $this->request->data['Distribution']['year'],
						'user' => AuthComponent::user('id')
					));
				$this->Distribution->save($data);

				$distribution->asXML("xmls/".$this->Distribution->field('salt').".xml");
				$name = $this->Distribution->field('salt');

			}
			/* Fim do XML */

			$teachers = $this->Teacher->find('all');
			$t = array();
			foreach ($teachers as $key => $value) {
				$t[$value['Teacher']['id']] = $value;
			}
			$this->set('teachers',$t);

			/* Seto a lista de professores para os Selects */

			$list1 = $this->Teacher->find('list', array('order' => array('Teacher.name' => 'ASC')));
			foreach ($list1 as $key => $value)
				if(!isset($this->request->data[$key][0]))
					unset($list1[$key]);

			$this->set('list1', $list1);
			
			$list2 = $this->Teacher->find('list', array('order' => array('Teacher.name' => 'ASC')));
			foreach ($list1 as $key => $value)
				if(!isset($this->request->data[$key][1]))
					unset($list2[$key]);
			$this->set('list2', $list2);

			/* Seto a lista de professores e disciplinas com as suas informações */

			$disciplines = $this->Discipline->find('all', array('order' => array('Discipline.name' => 'ASC')));
			$t = array();
			foreach ($disciplines as $key => $value) {
				$t[$value['Discipline']['id']] = $value;
			}
			$this->set('disciplines', $t);



			/* Crio a instância do core com os professores */

			$p = new Process(array(
					'countDiscipline' => $this->DisciplinesTeacher->countWeights(),
					'weights' => $this->DisciplinesTeacher->find('all', array('order' => array('DisciplinesTeacher.id' => 'ASC'))), 
					'discipline' => $this->Discipline->find('all', array('order' => array('Discipline.name' => 'ASC')))
				)
				, 'xmls/'.$name.'.xml', 4);
			$results = $p->run();
			$this->set('results', $results[0]);
			$this->set('rest1', $results[1]);
			$this->set('rest2', $results[2]);

			$this->set('weightsBefore', $p->statistics['before']);
			$this->set('weightsAfter', $p->statistics['after']);
			$this->render('/Elements/runGraph');
		}
	}

	public function beforeFilter(){
		parent::beforeFilter();
		if (!($this->request->params['action'] == 'viewNow'))
            $this->isAuthorized('admin');
	}
}

?>